home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
os2
/
pvm34b3.zip
/
pvm34b3
/
pvm3
/
tracer
/
trcmess.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-22
|
16KB
|
954 lines
static char rcsid[] =
"$Id: trcmess.c,v 4.2 1997/04/02 19:47:43 pvmsrc Exp $";
/*
* Tracer version 1.0: A Trace File Generator for PVM
* Oak Ridge National Laboratory, Oak Ridge TN.
* Authors: James Arthur Kohl and G. A. Geist
* (C) 1994 All Rights Reserved
*
* NOTICE
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted
* provided that the above copyright notice appear in all copies and
* that both the copyright notice and this permission notice appear
* in supporting documentation.
*
* Neither the Institution, Oak Ridge National Laboratory, nor the
* Authors make any representations about the suitability of this
* software for any purpose. This software is provided ``as is''
* without express or implied warranty.
*
* Tracer was funded by the U.S. Department of Energy.
*/
/* Tracer Library Header */
#include "trclib.h"
/* Routines */
int
trc_recv_messages( ID, max_count, status )
TRC_ID ID;
int max_count;
int *status;
{
static int *tids = (int *) NULL;
static int ntids = 0;
TRC_HOST H;
TRC_ID DEAD_ID_last;
TRC_ID DEAD_ID_next;
TRC_ID DEAD_ID;
int msgtag;
int others;
int ecnt;
int cnt;
int len;
int mid;
int num;
int tid;
int src;
int tmp;
int cc;
int i;
/* Verify Message Codes Set */
if ( TRC_HOST_ADD_NOTIFY_CODE == -1
|| TRC_HOST_DEL_NOTIFY_CODE == -1
#ifndef USE_PVM_33
|| ID->event_ctx == -1 || ID->output_ctx == -1
#endif
|| ID->event_tag == -1 || ID->output_tag == -1 )
{
printf( "Error: Message Codes Not Set - %d %d %d %d %d %d\n",
TRC_HOST_ADD_NOTIFY_CODE, TRC_HOST_DEL_NOTIFY_CODE,
ID->event_ctx, ID->output_ctx,
ID->event_tag, ID->output_tag );
return( -1 );
}
/* Clear Out Flags */
if ( status != NULL )
*status = TRC_MSG_STATUS_NONE;
/* Init Event Counter */
ecnt = 0;
/* Check for Host Sync Updates */
ecnt += trc_check_host_sync( ID );
/* Receive Stuff */
cnt = 0;
while ( cnt < max_count
&& (mid = trc_get_msg( ID, &len, &msgtag, &src, &others )) > 0 )
{
/* Set Activity Flag */
if ( status != NULL )
*status |= TRC_MSG_STATUS_ACTIVE;
/* Host Added */
if ( msgtag == TRC_HOST_ADD_NOTIFY_CODE && src == 0x80000000 )
{
cc = pvm_upkint( &num, 1, 1 );
if ( cc < 0 )
pvm_perror( "Error Unpacking Host Add Notify" );
else
{
if ( num > ntids )
{
ntids = num * 2;
if ( tids )
free( tids );
tids = (int *) malloc( (unsigned) ntids
* sizeof(int) );
trc_memcheck( tids, "Host Add Notify Tids Array" );
}
cc = pvm_upkint( tids, num, 1 );
if ( cc < 0 )
pvm_perror( "Error Unpacking Host Add TIDs" );
else
{
pvm_notify( PvmHostDelete, 100, num, tids );
ecnt += trc_handle_host_add_notify( ID, tids, num );
}
}
}
/* Host Deleted */
else if ( msgtag == TRC_HOST_DEL_NOTIFY_CODE
&& src == 0x80000000 )
{
cc = pvm_upkint( &tid, 1, 1 );
if ( cc < 0 )
pvm_perror( "Error Unpacking Host Delete Notify" );
else
ecnt += trc_handle_host_del_notify( ID, tid );
}
/* PVM Trace Event */
else if ( msgtag == ID->event_tag )
{
ecnt += trc_handle_trace_message( ID, src );
if ( status != NULL )
{
if ( ecnt )
*status |= TRC_MSG_STATUS_OVERWRITE;
else
*status |= TRC_MSG_STATUS_CLEANUP;
}
}
/* PVM Output Event */
else if ( msgtag == ID->output_tag )
{
ecnt += trc_handle_output_message( ID );
if ( status != NULL )
{
if ( ecnt )
*status |= TRC_MSG_STATUS_OVERWRITE;
else
*status |= TRC_MSG_STATUS_CLEANUP;
}
}
/* Unknown Message */
else
{
fprintf( stderr,
"Tracer: msg from 0x%x code %d len %d ?\n",
src, msgtag, len );
}
if ( pvm_freebuf( mid ) < 0 )
pvm_perror( "Error Freeing Message Buffer" );
cnt++;
}
if ( mid < 0 )
{
pvm_perror( "PVM System Failure" );
printf( "Tracer exiting...\n" );
return( -1 );
}
if ( status != NULL )
{
if ( cnt == max_count )
*status |= TRC_MSG_STATUS_MORE;
}
/* Try Flushing Dead IDs */
if ( others )
{
DEAD_ID = TRC_DEAD_ID_LIST;
DEAD_ID_last = (TRC_ID ) NULL;
while ( DEAD_ID != NULL )
{
trc_recv_messages( DEAD_ID, 1, &tmp );
if ( status != NULL )
*status |= tmp;
if ( trc_tevtasks_dead( DEAD_ID ) )
{
DEAD_ID_next = DEAD_ID->next;
if ( DEAD_ID_last != NULL )
DEAD_ID_last->next = DEAD_ID_next;
else
TRC_DEAD_ID_LIST = DEAD_ID_next;
trc_free_tracer_id( &DEAD_ID );
DEAD_ID = DEAD_ID_next;
}
else
{
DEAD_ID_last = DEAD_ID;
DEAD_ID = DEAD_ID->next;
}
}
}
return( ecnt );
}
int
trc_get_msg( ID, len, msgtag, src, others )
TRC_ID ID;
int *len;
int *msgtag;
int *src;
int *others;
{
int mid;
int tag;
/* Reset "Others" Flag */
if ( others != NULL )
*others = TRC_FALSE;
/* Check for Host Add */
if ( (mid = pvm_nrecv( -1, TRC_HOST_ADD_NOTIFY_CODE )) > 0 )
{
if ( pvm_bufinfo( mid, len, msgtag, src ) < 0 )
{
pvm_perror( "Error Checking Message Buffer" );
return( -1 );
}
return( mid );
}
else if ( mid < 0 )
{
pvm_perror( "Error Checking Host Add Notify Message" );
return( -1 );
}
/* Check for Host Delete */
if ( (mid = pvm_nrecv( -1, TRC_HOST_DEL_NOTIFY_CODE )) > 0 )
{
if ( pvm_bufinfo( mid, len, msgtag, src ) < 0 )
{
pvm_perror( "Error Checking Message Buffer" );
return( -1 );
}
return( mid );
}
else if ( mid < 0 )
{
pvm_perror( "Error Checking Host Delete Notify Message" );
return( -1 );
}
/* Any message at all? */
if ( (mid = pvm_probe( -1, -1 )) > 0 )
{
if ( pvm_bufinfo( mid, len, &tag, src ) < 0 )
{
pvm_perror( "Error Checking Message Buffer" );
return( -1 );
}
if ( msgtag != NULL )
*msgtag = tag;
/* The next one's for us... */
if ( tag == ID->event_tag || tag == ID->output_tag )
{
pvm_setrbuf( mid );
return( mid );
}
/* Or not... */
else
{
if ( others != NULL )
*others = TRC_TRUE;
return( 0 );
}
}
/* System Error */
else if ( mid < 0 )
{
pvm_perror( "Error Probing for Trace / Output Messages" );
return( -1 );
}
/* No Messages */
else
return( 0 );
}
int
trc_handle_trace_message( ID, src )
TRC_ID ID;
int src;
{
TRC_DATADESC DD;
TRC_TEVDESC TD;
TRC_TEVTASK TT;
TRC_HOST H;
TRC_DID dptr;
char diddesc[1024];
char tmp[1024];
char did[8];
int desc_done;
int did_done;
int done;
int omit;
int entry_exit;
int dump_event;
int pvmd_tid;
int did_int;
int tusec;
int tsec;
int ecnt;
int eid;
int tid;
int dt;
int marker;
int nest;
ecnt = 0;
TRC_PVMCKERR( pvm_upkint( &marker, 1, 1 ),
"Unpacking Trace Message", return( ecnt ) );
/* Old PVM 3.3 Trace Format */
if ( marker > 0 )
{
tsec = marker;
TRC_PVMCKERR( pvm_upkint( &tusec, 1, 1 ),
"Event Parse Error", return( ecnt ) );
TRC_PVMCKERR( pvm_upkint( &tid, 1, 1 ),
"Event Parse Error", return( ecnt ) );
TRC_PVMCKERR( pvm_upkint( &eid, 1, 1 ),
"Event Parse Error", return( ecnt ) );
ecnt += trc_store_old_trace_event( ID, tsec, tusec, tid, eid );
return( ecnt );
}
/* New PVM 3.4 Format */
/* Get Task & Host Info */
TT = trc_get_tevtask_tid( ID, src );
pvmd_tid = pvm_tidtohost( src );
if ( !pvmd_tid )
pvmd_tid = pvm_tidtohost( TRC_TID );
H = trc_get_host_tid( pvmd_tid );
/* Set Leftover Event Omit Flag */
omit = ( ID->trace_out == NULL
|| ( TT != NULL && TRC_TASK_OMIT( TT ) ) )
? TRC_TRUE : TRC_FALSE;
/* Process Event Message */
nest = 0;
done = 0;
do
{
switch ( marker )
{
case TEV_MARK_EVENT_BUFFER:
{
nest++;
break;
}
case TEV_MARK_EVENT_BUFFER_END:
{
if ( !(--nest) )
done++;
break;
}
case TEV_MARK_DATA_ID:
{
did_done = 0;
do
{
TRC_PVMCKERR( pvm_upkint( &did_int, 1, 1 ),
"Data ID Message", return( ecnt ) );
if ( did_int != TEV_MARK_DATA_ID_END )
{
TRC_PVMCKERR( pvm_upkstr( did ),
"Data ID Name", return( ecnt ) );
TRC_PVMCKERR( pvm_upkstr( diddesc ),
"Data ID Description", return( ecnt ) );
dptr = (TRC_DID) trc_lookup_trie( TRC_DID_TRIE,
did );
if ( dptr == NULL
|| dptr->id != did_int
|| strcmp( dptr->desc, diddesc ) )
{
dptr = trc_create_did();
dptr->id = did_int;
dptr->name = trc_copy_str( did );
dptr->desc = trc_copy_str( diddesc );
dptr->next = TRC_DID_LIST;
TRC_DID_LIST = dptr;
trc_add_to_trie( TRC_DID_TRIE,
dptr->name, (void *) dptr );
}
trc_set_didlist( H, dptr );
}
else
did_done++;
}
while ( !did_done );
if ( !nest )
done++;
break;
}
case TEV_MARK_EVENT_DESC:
{
TD = trc_create_tevdesc();
TD->refcount = 1;
TRC_PVMCKERR( pvm_upkint( &eid, 1, 1 ),
"Event Descriptor ID", return( ecnt ) );
TD->eid = eid & ~( TEV_EVENT_ENTRY | TEV_EVENT_EXIT );
if ( eid & TEV_EVENT_ENTRY )
TD->entry_exit = TRC_ENTRY_TEV;
else if ( eid & TEV_EVENT_EXIT )
TD->entry_exit = TRC_EXIT_TEV;
else
TD->entry_exit = TRC_IGNORE_TEV;
TRC_PVMCKERR( pvm_upkstr( tmp ),
"Event Descriptor Name", return( ecnt ) );
TD->name = trc_copy_str( tmp );
desc_done = 0;
do
{
TRC_PVMCKERR( pvm_upkint( &did_int, 1, 1 ),
"Semantic Data ID", return( ecnt ) );
if ( did_int != TEV_MARK_EVENT_DESC_END )
{
if ( TD->ddesc == NULL )
DD = TD->ddesc = trc_create_datadesc();
else
DD = DD->next = trc_create_datadesc();
if ( H->didlist == NULL )
{
printf(
"Warning: Missing DID List For Host %s\n",
H->name );
}
DD->did = trc_get_did( H, did_int );
if ( DD->did == NULL )
{
printf( "Error: DID=%d Not Found\n",
did_int );
trc_free_tevdesc( &TD );
return( ecnt );
}
TRC_PVMCKERR( pvm_upkint( &dt, 1, 1 ),
"Data Type", return( ecnt ) );
DD->dt = dt &
~( TEV_DATA_SCALAR | TEV_DATA_ARRAY );
DD->array = dt &
( TEV_DATA_SCALAR | TEV_DATA_ARRAY );
if ( !trc_unpack_data_value( DD ) )
{
trc_free_tevdesc( &TD );
return( ecnt );
}
}
else
desc_done++;
}
while ( !desc_done );
dump_event = trc_add_tevdesc( ID, &TD, src, omit );
trc_set_tevlist( TT, H, TD );
if ( TD->dump )
trc_dump_tevdesc( ID, TD, src );
if ( dump_event )
trc_store_data_values( ID, TD, src, omit );
if ( !omit )
ecnt++;
if ( !nest )
done++;
break;
}
case TEV_MARK_USER_EVENT_RECORD:
{
TD = trc_create_tevdesc();
TD->refcount = 1;
TRC_PVMCKERR( pvm_upkint( &eid, 1, 1 ),
"Event Descriptor ID", return( ecnt ) );
TD->eid = eid & ~( TEV_EVENT_ENTRY | TEV_EVENT_EXIT );
if ( eid & TEV_EVENT_ENTRY )
TD->entry_exit = TRC_ENTRY_TEV;
else if ( eid & TEV_EVENT_EXIT )
TD->entry_exit = TRC_EXIT_TEV;
else
TD->entry_exit = TRC_IGNORE_TEV;
TRC_PVMCKERR( pvm_upkstr( tmp ),
"Event Descriptor Name", return( ecnt ) );
TD->name = trc_copy_str( tmp );
/* Yank Out Hardwired Timestamp */
DD = TD->ddesc = trc_create_datadesc();
DD->did = trc_get_did( (TRC_HOST) NULL, TEV_DID_TS );
DD->dt = TEV_DATA_INT;
DD->array = TEV_DATA_SCALAR;
if ( !trc_unpack_data_value( DD ) )
{
trc_free_tevdesc( &TD );
return( ecnt );
}
DD = DD->next = trc_create_datadesc();
DD->did = trc_get_did( (TRC_HOST) NULL, TEV_DID_TU );
DD->dt = TEV_DATA_INT;
DD->array = TEV_DATA_SCALAR;
if ( !trc_unpack_data_value( DD ) )
{
trc_free_tevdesc( &TD );
return( ecnt );
}
desc_done = 0;
do
{
TRC_PVMCKERR( pvm_upkint( &dt, 1, 1 ),
"Data Type", return( ecnt ) );
if ( dt != TEV_MARK_USER_EVENT_RECORD_END )
{
DD = DD->next = trc_create_datadesc();
DD->dt = dt &
~( TEV_DATA_SCALAR | TEV_DATA_ARRAY );
DD->array = dt &
( TEV_DATA_SCALAR | TEV_DATA_ARRAY );
if ( !trc_unpack_data_value( DD ) )
{
trc_free_tevdesc( &TD );
return( ecnt );
}
}
else
desc_done++;
}
while ( !desc_done );
dump_event = trc_add_tevdesc( ID, &TD, src, omit );
if ( TD->dump )
trc_dump_tevdesc( ID, TD, src );
if ( dump_event )
trc_store_data_values( ID, TD, src, omit );
if ( !omit )
ecnt++;
if ( !nest )
done++;
break;
}
case TEV_MARK_EVENT_RECORD:
{
TRC_PVMCKERR( pvm_upkint( &eid, 1, 1 ),
"Event ID", return( ecnt ) );
if ( eid & TEV_EVENT_ENTRY )
entry_exit = TRC_ENTRY_TEV;
else if ( eid & TEV_EVENT_EXIT )
entry_exit = TRC_EXIT_TEV;
else
entry_exit = TRC_IGNORE_TEV;
eid &= ~( TEV_EVENT_ENTRY | TEV_EVENT_EXIT );
TD = trc_get_tevdesc( TT, H, eid, entry_exit );
if ( TD != NULL )
{
if ( trc_store_trace_event( ID, TD, src, omit ) )
ecnt++;
}
else
printf( "Error: Descriptor Not Found\n\n" );
if ( !nest )
done++;
break;
}
}
if ( !done )
{
TRC_PVMCKERR( pvm_upkint( &marker, 1, 1 ),
"Unpacking Trace Message", return( ecnt ) );
}
}
while ( !done );
return( ecnt );
}
int
trc_handle_output_message( ID )
TRC_ID ID;
{
TRC_TEVTASK TT;
char tmp[255];
char msg[255];
char *output;
int ecnt;
int omit;
int len;
int tid;
ecnt = 0;
TRC_PVMCKERR( pvm_upkint( &tid, 1, 1 ),
"Error Unpacking Output Message", return( ecnt ) );
TRC_PVMCKERR( pvm_upkint( &len, 1, 1 ),
"Error Unpacking Output Length", return( ecnt ) );
/* Set Leftover Event Omit Flag */
TT = trc_get_tevtask_tid( ID, tid );
omit = ( ID->trace_out == NULL
|| ( TT != NULL && TRC_TASK_OMIT( TT ) ) )
? TRC_TRUE : TRC_FALSE;
/* Unpack Output */
if ( len > 0 )
{
output = (char *) malloc( (unsigned) ( len + 1 )
* sizeof(char) );
trc_memcheck( output, "PVM Output String" );
TRC_PVMCKERR( pvm_upkbyte( output, len, 1 ),
"Error Unpacking Task Output",
free(output); return( ecnt ) );
output[ len ] = '\0';
if ( !omit )
ecnt = trc_store_output_event( ID, tid, output, len );
free( output );
}
else
{
switch ( len )
{
case 0:
{
if ( !omit )
{
sprintf( tmp, "GOTEOF\n" );
ecnt = trc_store_output_event( ID,
tid, tmp, strlen(tmp) );
}
if ( TT != NULL )
{
if ( TT->tevstatus == TRC_TASK_ALIVE )
{
TT->outstatus = TRC_TASK_EOF;
trc_check_for_dead_host( ID, TT );
if ( !trc_tevtasks_alive( ID ) )
trc_end_trace( ID );
}
else
TT->outstatus = TRC_TASK_EOF;
}
else if ( !omit )
{
printf(
"\nWarning: GOTEOF Unknown Task TID=0x%x.\n\n",
tid );
}
break;
}
case -1:
{
if ( omit )
break;
sprintf( tmp, "GOTSPAWN\n" );
ecnt = trc_store_output_event( ID,
tid, tmp, strlen(tmp) );
if ( TT == NULL )
{
sprintf( msg, "Task TID=0x%x Connected to %s",
tid, TRC_NAME );
trc_status_msg( ID, msg );
TT = trc_create_tevtask();
TT->tid = tid;
TT->outstatus = TRC_TASK_OUT;
TT->tevstatus = TRC_TASK_NOLIFE;
TT->next = ID->tevtask_list;
ID->tevtask_list = TT;
}
else
TT->outstatus = TRC_TASK_OUT;
break;
}
case -2:
{
if ( omit )
break;
sprintf( tmp, "CREATION\n" );
ecnt = trc_store_output_event( ID,
tid, tmp, strlen(tmp) );
if ( TT == NULL )
{
sprintf( msg, "Task TID=0x%x Connected to %s",
tid, TRC_NAME );
trc_status_msg( ID, msg );
TT = trc_create_tevtask();
TT->tid = tid;
TT->outstatus = TRC_TASK_OUT;
TT->tevstatus = TRC_TASK_NOLIFE;
TT->next = ID->tevtask_list;
ID->tevtask_list = TT;
}
else
TT->outstatus = TRC_TASK_OUT;
break;
}
default:
{
if ( !omit )
{
fprintf( stderr,
"Console: unknown output msg 0x%x?\n", tid );
}
}
}
}
return( ecnt );
}